package com.hfdg.prototype.base.generator;


import com.alibaba.druid.pool.DruidDataSource;
import com.hfdg.content.entity.Content;
import com.hfdg.coordination.entity.CoordTask;
import com.hfdg.prototype.base.annotations.Table;
import com.hfdg.prototype.base.utils.CamelUtils;
import com.hfdg.prototype.base.utils.SqlBuilder;
import com.hfdg.prototype.base.utils.TimeUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.core.JdbcTemplate;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @ClassName CodeGenerator
 * @Description TODO 代码生成器
 * @Author yuelh
 * @Date 2019/1/17 19:15
 * @Version 1.0
 * @Company 会飞的锅工作室
 **/
public class CodeGenerator {
//    private static final String BASE_PATH="D:/gen/";
    private static final Resource RESOURCE = new ClassPathResource("gen");
    private static String company="会飞的锅工作室";
    private static String author="yuelh";
    private static String  email="18695867679@163.com";
    private static String  category;
    private static Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
    private static File baseDir;
    static{
        baseDir = new File(System.getProperty("user.dir")+File.separator+"src"+File.separator+"main");
        System.out.println(baseDir.getAbsolutePath());
        if(!baseDir.exists()){
            baseDir.mkdirs();
        }
    }
    /*
     * @Author yuelh
     * @Company hfdg
     * @Description //TODO   mapper生成，含xml以及接口类
     * @Date 19:22 2019/1/17
     * @Param [clazz]
     * @return void
     **/
    public static void generateMapperXml(Class<?> clazz){
        try {
            configuration.setDirectoryForTemplateLoading(RESOURCE.getFile());
            File xmlMapperFile = RESOURCE.getFile();
            Template mapperXml = configuration.getTemplate("mapperXml.ftl");
            Field[] fields = FieldUtils.getAllFields(clazz);
            List<String> columnList = new ArrayList<>();
            List<ColumnField> columnFieldList = new ArrayList<>();
            for(Field field:fields){
                columnList.add(CamelUtils.camel2Underline(field.getName()));
                columnFieldList.add(ColumnField.build(field));
            }
            String tableName = clazz.getAnnotation(Table.class).name();
            Map<String,Object> params = new HashMap<>();
            params.put("fields",fields);
            params.put("columnList",columnList);
            params.put("columnFieldList",columnFieldList);
            params.put("tableName",tableName);
            params.put("tableInitSql", SqlBuilder.tableInit(clazz));
            params.put("type",clazz.getName());
            String packageName = ClassUtils.getPackageName(clazz);
            params.put("namespace",packageName.substring(0,packageName.lastIndexOf("."))+".mapper."+clazz.getSimpleName()+"Mapper");
            String mapperPackage = packageName.substring(0,packageName.lastIndexOf("."))+".mapper";
            String mapperRelativePath=mapperPackage.replace(".","\\");
            File mapperXmlBaseDir = new File(baseDir+File.separator+"resources"+File.separator+"mybatis"+File.separator+mapperRelativePath+File.separator);
            if(!mapperXmlBaseDir.exists()){
                mapperXmlBaseDir.mkdirs();
            }
            File mapperXmlFile = new File(mapperXmlBaseDir,clazz.getSimpleName()+"Mapper.xml");
            if(!mapperXmlFile.exists()){
                mapperXmlFile.createNewFile();
                System.out.println(mapperXmlFile.getAbsolutePath()+"<==");
            }
            mapperXml.process(params,new FileWriter(mapperXmlFile));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        }
    }
    /*
     * @Author yuelh
     * @Company hfdg
     * @Description //TODO  生成Mapper 接口类
     * @Date 11:38 2019/1/19
     * @Param [clazz]  要操作的数据库表对应的实体类
     * @return void
     **/
    public static void generateMapper(Class<?> clazz){
        try {
            configuration.setDirectoryForTemplateLoading(RESOURCE.getFile());
            File xmlMapperFile = RESOURCE.getFile();
            Template mapper = configuration.getTemplate("mapper.ftl");
            String modelPackage = ClassUtils.getPackageName(clazz);
            String mapperPackage = modelPackage.substring(0,modelPackage.lastIndexOf("."))+".mapper";
            String modelFullName = clazz.getName();
            String modelSimpleName=clazz.getSimpleName();
            Map<String,Object> root = new HashMap<>();
            root.put("mapperPackage",mapperPackage);
            root.put("modelName",clazz.getSimpleName());
            root.put("mapperName",clazz.getSimpleName()+"Mapper");
            root.put("modelFullName",modelFullName);
            root.put("company",company);
            root.put("author",author);
            root.put("email",email);
            String mapperRelativePath=mapperPackage.replace(".","\\");
            File mapperBaseDir = new File(baseDir+File.separator+"java"+File.separator+mapperRelativePath+File.separator);
            if(!mapperBaseDir.exists()){
                mapperBaseDir.mkdirs();
            }
            File mapperFile = new File(mapperBaseDir,clazz.getSimpleName()+"Mapper.java");
            if(!mapperFile.exists()){
                mapperFile.createNewFile();
            }
            mapper.process(root,new FileWriter(mapperFile));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        }
    }
    public static void generateService(Class<?> clazz){
        try {
            configuration.setDirectoryForTemplateLoading(RESOURCE.getFile());
            File xmlMapperFile = RESOURCE.getFile();
            Template service = configuration.getTemplate("service.ftl");
            Template serviceImpl = configuration.getTemplate("serviceImpl.ftl");
            String modelName = clazz.getSimpleName();
            String modelFullName = clazz.getName();
            String modelPackage = ClassUtils.getPackageName(clazz);
            String mapperPackage = modelPackage.substring(0,modelPackage.lastIndexOf("."))+".mapper";
            String servicePackage = modelPackage.substring(0,modelPackage.lastIndexOf("."))+".service";
            String serviceImplPackage = modelPackage.substring(0,modelPackage.lastIndexOf("."))+".serviceImpl";
            String modelSimpleName=clazz.getSimpleName();
            Map<String,Object> root = new HashMap<>();
            root.put("modelName",modelName);
            root.put("modelPackage",modelPackage);
            root.put("mapperPackage",mapperPackage);
            root.put("servicePackage",servicePackage);
            root.put("company",company);
            root.put("author",author);
            root.put("email",email);
            String serviceRelativePath=servicePackage.replace(".","\\");
            File serviceBaseDir = new File(baseDir+File.separator+"java"+File.separator+serviceRelativePath+File.separator);
            if(!serviceBaseDir.exists()){
                serviceBaseDir.mkdirs();
            }
            File serviceImplBaseDir = new File(baseDir+File.separator+"java"+File.separator+serviceRelativePath+File.separator+"impl"+File.separator);
            if(!serviceImplBaseDir.exists()){
                serviceImplBaseDir.mkdirs();
            }
            File serviceFile = new File(serviceBaseDir,modelName+"Service.java");
            File serviceImplFile = new File(serviceImplBaseDir,modelName+"ServiceImpl.java");
            if(!serviceFile.exists()){
                serviceFile.createNewFile();
            }
            if(!serviceImplFile.exists()){
                serviceImplFile.createNewFile();
            }
            service.process(root,new FileWriter(serviceFile));
            serviceImpl.process(root,new FileWriter(serviceImplFile));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        }
    }
    public static void generateCtrl(Class<?> clazz){
        try {
            configuration.setDirectoryForTemplateLoading(RESOURCE.getFile());
            File xmlMapperFile = RESOURCE.getFile();
            Template ctrl = configuration.getTemplate("ctrl.ftl");
            String modelName = clazz.getSimpleName();
            String modelFullName = clazz.getName();
            String modelPackage = ClassUtils.getPackageName(clazz);
            String ctrlPackage = modelPackage.substring(0,modelPackage.lastIndexOf("."))+".ctrl";
            String servicePackage = modelPackage.substring(0,modelPackage.lastIndexOf("."))+".service";
            Map<String,Object> root = new HashMap<>();
            root.put("modelName",modelName);
            root.put("modelPackage",modelPackage);
            root.put("ctrlPackage",ctrlPackage);
            root.put("servicePackage",servicePackage);
            root.put("company",company);
            root.put("author",author);
            root.put("email",email);
            root.put("category",category);
            String ctrlRelativePath=ctrlPackage.replace(".","\\");
            File ctrlBaseDir = new File(baseDir+File.separator+"java"+File.separator+ctrlRelativePath+File.separator);
            if(!ctrlBaseDir.exists()){
                ctrlBaseDir.mkdirs();
            }
            File ctrlFile = new File(ctrlBaseDir,modelName+"Ctrl.java");
            if(!ctrlFile.exists()){
                ctrlFile.createNewFile();
            }
            System.out.println(ctrlFile.getAbsolutePath());
            ctrl.process(root,new FileWriter(ctrlFile));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        }
    }
    public static void dbTableInit(Class<?> clazz){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/prototype?useSSL=false&serverTimezone=Asia/Shanghai&useLegacyDatetimeCode=false&autoReconnect=true&failOverReadOnly=false&useUnicode=true&characterEncoding=UTF-8\n");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("123456");
        JdbcTemplate jdbcTemplate = new JdbcTemplate(druidDataSource);
        String tableInitSql =SqlBuilder.tableInit(clazz);
        String dropSql = tableInitSql.split(";")[0];
        String createSql = tableInitSql.split(";")[1];
        System.out.println(tableInitSql);
        jdbcTemplate.execute(dropSql);
        jdbcTemplate.execute(createSql);

    }

    public static void generate(){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入生成类型，单类生成（1），包名批量生成（2）：");
        String type = sc.nextLine();
        if("1".equals(type.trim())){
            System.out.println("请输入生类名：");
            String className = sc.nextLine();
        }else if("2".equals(type.trim())){
            System.out.println("请输入包名：");
            String packageName = sc.nextLine();
        }
        System.out.println("请输入模块名：");
        category =sc.nextLine();
        System.out.println("请输入作者（yuelh）：");
        String author =sc.nextLine();
        if(StringUtils.isBlank(author)){
            author="yuelh";
        }
        System.out.println("请输入公司（会飞的锅工作室）：");
        String company =sc.nextLine();
        if(StringUtils.isBlank(company)){
            company="会飞的锅工作室";
        }
    }

    public static void main(String[] args) {
        category="coordination";
//        List<String> classNames = SqlBuilder.getClassName("com.hfdg.coordination.entity");
//        for(String className:classNames){
//            System.out.println(className);
//            try {
//                Class clazz = Class.forName(className);
//                generateMapperXml(clazz);
//                generateMapper(clazz);
//                generateService(clazz);
//                generateCtrl(clazz);
//                dbTableInit(clazz);
//            } catch (ClassNotFoundException e) {
//                e.printStackTrace();
//            }
//
//        }
//        Class clazz = com.hfdg.filecenter.entity.File.class;class
//        generateMapperXml(clazz);
//        generateMapper(clazz);
//        generateService(clazz);
//        generateCtrl(clazz);
//        dbTableInit(clazz);


    }
}
